package gla.centralhotel.dao;

import gla.centralhotel.dao.interfaces.IHotelDAO;
import gla.centralhotel.exception.CollectionRetrieverException;
import gla.centralhotel.exception.SubscriptionManagementException;
import gla.centralhotel.exception.TooLongTextException;
import gla.centralhotel.model.Hotel;
import gla.centralhotel.model.Manager;
import gla.centralhotel.model.Zipcode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Rivo
 */
@Stateless
public class HotelDAO implements IHotelDAO {

    @PersistenceContext
    private EntityManager em;

    private Hotel create(Hotel hotel) {
        em.persist(hotel);
        return hotel;
    }

    public Hotel edit(Hotel hotel) {
        em.merge(hotel);
        return hotel;
    }

    public void remove(Hotel hotel) {
        em.remove(em.merge(hotel));
    }

    public Hotel find(Object id) {
        return em.find(gla.centralhotel.model.Hotel.class, id);
    }

    public List<Hotel> findAll() {
        return em.createQuery("select object(o) from Hotel as o").getResultList();
    }

    /**
     * Récupère tous les hotels d'un manager
     * @param manager
     * @return
     * @throws gla.centralhotel.exception.CollectionRetrieverException
     */
    public ArrayList<Hotel> getAllHotelByManager(Manager manager) throws CollectionRetrieverException {
        String query = "select htl from Hotel as htl where htl.refManager = :refManager";
        Query q = em.createQuery(query);
        q.setParameter("refManager", manager);

        try {
            List<Hotel> hotels = q.getResultList();
            return new ArrayList(hotels);
        } catch (IllegalStateException ex) {
            ex.printStackTrace();
            throw new CollectionRetrieverException("Erreur de récupération des hotels en fonction du manager");
        }
    }

    /**
     * Ajoute ou met à jour l'hotel s'il a une refManager
     * @param hotel
     * @return
     * @throws gla.centralhotel.exception.SubscriptionManagementException
     */
    public Hotel saveHotel(Hotel hotel) throws SubscriptionManagementException, TooLongTextException{
        String desc = hotel.getDescription();
        String sce = hotel.getServicesEquipments();
        if(desc.length() > 255 || sce.length() > 255){
            throw new TooLongTextException("Description ou service trop long 255 caractères max !!");
        }
        if (hotel.getId() == null) {
            if (hotel.getRefManager() != null) {
                return create(hotel);
            } else {
                throw new SubscriptionManagementException("Erreur grave, enregistrement d'hotel sans manager!!!");
            }
        } else if (hotel.getRefManager() != null) {
            return edit(hotel);
        } else {
            throw new SubscriptionManagementException("Erreur grave, enregistrement d'hotel sans manager!!!");
        }
    }
    
    /**
     * retourne la liste des hotel dans une ville
     * @param z
     * @return
     * @throws gla.centralhotel.exception.CollectionRetrieverException
     */
    public ArrayList<Hotel> getHotelByZipcode(Zipcode z) throws CollectionRetrieverException
    {
        ArrayList<Hotel> alh = new ArrayList<Hotel>();
        Query q = em.createQuery("select h from Hotel as h where h.refZipcode = :ref ");
        q.setParameter("ref", z);
        q.getResultList();
        try{
            return new ArrayList(q.getResultList());
        }catch(IllegalStateException ex){
            ex.printStackTrace();
            throw new CollectionRetrieverException("Erreur de recuperation des hotel par ville");
        }
    }
}
